package com.ch.engine.config;

import com.ch.common.result.Result;
import com.ch.common.result.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;

/**
 * 自定义的公共异常处理器
 * 1.声明异常处理器
 * 2.对异常统一处理
 *
 * @author admin
 */
@Slf4j
@ControllerAdvice
public class BaseExceptionHandler {

    /**
     * body参数校验(带@RequestBody注解)
     *
     * @param e 异常
     * @return com.ch.common.result.Result
     * @author wangchunhui
     * @date 2025/3/25 11:15
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Result handlerMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("handlerMethodArgumentNotValidException：{}", toStr(e));
        return new Result(ResultCode.INVALID_PARAMS, toStr(e));
    }

    /**
     * body参数校验(带@RequestBody注解)
     *
     * @param e 异常
     * @return com.ch.common.result.Result
     * @author wangchunhui
     * @date 2025/3/25 11:15
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Result handlerConstraintViolationException(ConstraintViolationException e) {
        log.error("handlerConstraintViolationException：{}", toStr(e));
        return new Result(ResultCode.INVALID_PARAMS, toStr(e));
    }


    private String toStr(MethodArgumentNotValidException e) {
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        return fieldErrors.stream()
                .map(t -> t.getField() + ":" + t.getDefaultMessage())
                .reduce((s, s2) -> s + ", " + s2).orElse("");
    }

    private String toStr(ConstraintViolationException e) {
        Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
        return constraintViolations.stream()
                .map(t -> t.getPropertyPath().toString() + ":" + t.getMessage())
                .reduce((s, s2) -> s + ", " + s2).orElse("");
    }
}
